﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Flicker_Application.Flicker_ServiceReference;
using System.Windows.Browser;
using System.Windows.Media.Imaging;

namespace Flicker_Application
{
    public partial class MainPage : UserControl
    {
        FlickerServiceSoapClient client;
        String pid="", PhotoUrl = "", Title;

        String FbApi = "196958213750081";

        private Storyboard _sb = new Storyboard();
        private TimeSpan _tsLastFrame = new TimeSpan();
        private bool _front = true;

        public MainPage()
        {
            InitializeComponent();
            client = new FlickerServiceSoapClient();
            client.GetPhotosByNameCompleted += new EventHandler<GetPhotosByNameCompletedEventArgs>(OnPhotoResponse);
            client.GetCommentsCompleted += new EventHandler<GetCommentsCompletedEventArgs>(OnRequestComments);            

            //Design Codes
            TransformGroup transforms = new TransformGroup();
            ScaleTransform scale = new ScaleTransform();

            transforms.Children.Add(scale);
            this.screens.RenderTransform = transforms;

            Storyboard sbForward = new Storyboard();
            AnimateFlip(_sb, scale, out _tsLastFrame);

            this.LayoutRoot.Resources.Add("Animation", _sb);
            this.flip_Img.MouseLeftButtonUp += new MouseButtonEventHandler(Flip_MouseLeftButtonDown);
            
        }

        public void UpdateFaceBookUrl(String url)
        {
            string encurl = System.Windows.Browser.HttpUtility.UrlEncode(url);
            String src = "'http://www.facebook.com/plugins/like.php?href=" + encurl +
                "&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80' scrolling='no' frameborder='0' style='border:none; overflow:hidden; width:450px; height:80px;'";
            htmlHost.SourceHtml = "<iframe src=" + src + "></iframe>";
            //htmlHost.SourceHtml = "<iframe src='http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.facebook.com%2Fpages%2FXAMLBlogCOM%2F175966469116158&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light&amp;height=80' scrolling='no' frameborder='0' style='border:none; overflow:hidden; width:450px; height:80px;'></iframe>";
        }

        


        private void OnPhotoResponse(object sender, GetPhotosByNameCompletedEventArgs e)
        {
            try
            {
                // So that we can handle the error in the exception block
                if (e.Error != null)
                    throw e.Error;

                if (e.Result.Count == 0)
                {
                    //show error
                    this.ErrorTextBlock.Visibility = Visibility.Visible;
                    return;
                }

                if (e.Result != null)
                {
                    this.lbPhotos.ItemsSource = e.Result;
                    //show first pic by default
                    this.RightStackPanel.DataContext = e.Result[0];
                    RequestComments(e.Result[0].PhotoId);
                    lblTitle.Text = e.Result[0].Title;
                    lblUrl.Text = e.Result[0].LargeUrl;

                    //this.ScrollViewer.Visibility = Visibility.Visible;
                    this.RightStackPanel.Visibility = Visibility.Visible;
                    this.ErrorTextBlock.Visibility = Visibility.Collapsed;
                    this.PhotoUrl = e.Result[0].LargeUrl;
                    UpdateFaceBookUrl(PhotoUrl);
                    this.zoom_in.Visibility = System.Windows.Visibility.Visible;
                    this.zoom_out.Visibility = System.Windows.Visibility.Visible;
                    
                }
            }
            catch (Exception exception)
            {
                HtmlPage.Window.Alert("service_GetRandomPicsCompleted:" + exception.ToString());
            }
        }


        private void RequestComments(string pid)
        {
            client.GetCommentsAsync(pid);
            this.pid = pid;
        }

        private void OnRequestComments(object sender, GetCommentsCompletedEventArgs e)
        {
            try
            {
                if (e.Error != null)
                    throw e.Error;

                if (e.Result != null && e.Result.Count > 0)
                {
                    //this.CommentGrid.ItemsSource = e.Result;
                    this.CommentStack.Visibility = Visibility.Visible;
                    this.NoComments.Visibility = Visibility.Collapsed;
                    lblComment.Text = e.Result[0].CommentHtml;
                    lblDateCreated.Text = e.Result[0].DateCreated.ToString();                    
                    
                    List<Comments> comments = e.Result.ToList();
                    lblComment.Text = comments[0].CommentHtml;
                }
                else
                {
                    this.CommentStack.Visibility = Visibility.Collapsed;
                    this.NoComments.Visibility = Visibility.Visible;
                }
            }
            catch (Exception exception)
            {
                HtmlPage.Window.Alert("service_GetCommentsCompleted:" + exception.ToString());
            }
        }

        private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Photo photo = (Photo)((Image)sender).DataContext;
            RequestComments(photo.PhotoId);
            this.RightStackPanel.DataContext = photo;
            RequestComments(photo.PhotoId);

            lblTitle.Text = photo.Title;
            lblUrl.Text = photo.LargeUrl;
            UpdateFaceBookUrl(photo.LargeUrl);
        }


        /// <summary>
        /// Animation event handlers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {            
            client.GetPhotosByNameAsync(this.UsernameTextbox.Text);
        }



        #region Design and Animation Codes

        void Flip_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (_front)
            {
                _sb.Pause();
                _sb.AutoReverse = false;
                _sb.Begin();
                _front = false;

                
               zoom_in.Visibility = System.Windows.Visibility.Collapsed;
               zoom_out.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                zoom_in.Visibility = System.Windows.Visibility.Visible;
                zoom_out.Visibility = System.Windows.Visibility.Visible;
                _sb.Pause();
                _sb.AutoReverse = true;
                _sb.Seek(_tsLastFrame);
                _sb.Resume();

                _front = true;
            }
        }       

        private TimeSpan AnimateFlip(Storyboard sb, ScaleTransform scale, out TimeSpan tsLastFrame)
        {
            double speed = 4;
            double flipRotation = 0;
            double flipped = 2;
            tsLastFrame = new TimeSpan();
            TimeSpan tsSideFlipped = new TimeSpan();

            int frames = 1;
            DoubleAnimationUsingKeyFrames daX = new DoubleAnimationUsingKeyFrames();
            tsLastFrame = new TimeSpan();
            while (flipRotation != flipped * 180)
            {
                flipRotation += speed;
                double flipRadian = flipRotation * (Math.PI / 180);
                double size = Math.Cos(flipRadian);
                double scalar = (1 / (1 / size));

                DiscreteDoubleKeyFrame ddkfX = new DiscreteDoubleKeyFrame();
                ddkfX.Value = (size * scalar);

                tsLastFrame = TimeSpan.FromMilliseconds(frames * 7);

                //the first time we flip to negative capture the tsLastFrame so we know when we will need to
                //visualize the flip side
                flipped = (size < 0) ? +1 : +0;
                if (flipped == 1 && tsSideFlipped.Ticks == 0)
                {
                    tsSideFlipped = tsLastFrame;
                }

                ddkfX.KeyTime = KeyTime.FromTimeSpan(tsLastFrame);

                //add the DiscreteDoubleKeyFrame to the DoubleAnimationUsingKeyFrames
                daX.KeyFrames.Add(ddkfX);

                flipRotation %= 360;
                frames++;
            }

            Storyboard.SetTarget(daX, scale);
            Storyboard.SetTargetProperty(daX, new PropertyPath("(ScaleX)"));
            sb.Children.Add(daX);

            VisualizeSide(sb, tsSideFlipped, 0, TimeSpan.FromMilliseconds((tsSideFlipped.Milliseconds + 100)), back.Opacity, this.back);
            VisualizeSide(sb, TimeSpan.FromMilliseconds((tsSideFlipped.Milliseconds - 100)), front.Opacity, tsSideFlipped, 0, this.front);
            back.Opacity = 0;
            return tsLastFrame;
        }

        private void VisualizeSide(Storyboard sb, TimeSpan tsStart, double opacityStart, TimeSpan tsEnd, double opacityEnd, UIElement side)
        {
            DoubleAnimationUsingKeyFrames daOpacity = new DoubleAnimationUsingKeyFrames();
            SplineDoubleKeyFrame sdkfStart = new SplineDoubleKeyFrame();
            sdkfStart.Value = opacityStart;
            sdkfStart.KeyTime = tsStart;
            sdkfStart.KeySpline = DefineKeySpline(0, 0, 1, 1);
            daOpacity.KeyFrames.Add(sdkfStart);

            SplineDoubleKeyFrame sdkfEnd = new SplineDoubleKeyFrame();
            sdkfEnd.Value = opacityEnd;
            sdkfEnd.KeyTime = tsEnd;
            sdkfEnd.KeySpline = DefineKeySpline(0, 0, 1, 1);
            daOpacity.KeyFrames.Add(sdkfEnd);

            Storyboard.SetTarget(daOpacity, side);
            Storyboard.SetTargetProperty(daOpacity, new PropertyPath("(UIElement.Opacity)"));

            sb.Children.Add(daOpacity);
        }

        private static KeySpline DefineKeySpline(double cp1X, double cp1Y, double cp2X, double cp2Y)
        {
            KeySpline ksStart = new KeySpline();
            ksStart.ControlPoint1 = new Point(cp1X, cp1Y);
            ksStart.ControlPoint2 = new Point(cp2X, cp2Y);
            return ksStart;
        }
        
        private void RightStackPanel_MouseEnter(object sender, MouseEventArgs e)
        {
            ((Storyboard)(sender as StackPanel).FindName("grow")).Begin();
        }

        private void RightStackPanel_MouseLeave(object sender, MouseEventArgs e)
        {
            ((Storyboard)(sender as StackPanel).FindName("shrink")).Begin();
        }

        private void Image1_MouseLeftButtonDown(object sender, RoutedEventArgs e)
        {
            zoom.Begin();
        }

        private void Image2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            zoom.Stop();
        }

        #endregion


    }
}
